#include <iostream>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ether.h>
#include <cstring>
#include <unistd.h>
#define BUF_SIZE 1024
#define DST_SIZE 7
#define SRC_SIZE 7
int main()
{
    int sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ARP));
    if (sockfd < 0)
    {
        std::cout << "socket fail" << std::endl;
        exit(1);
    }
    unsigned char buffer[1024];
    memset(buffer, 0, 1024);
    while (true)
    {
        ssize_t s = recvfrom(sockfd, buffer, 1024, 0, nullptr, nullptr);
        if (s < 0)
        {
            std::cout << "recvfrom fail" << std::endl;
            exit(2);
        }
        // 以太网数据包头
        std::cout << "以太网数据包报头" << std::endl;
        unsigned short type = 0;
        unsigned char dst[DST_SIZE] = "";
        unsigned char src[SRC_SIZE] = "";
        type = ntohs(*(unsigned short *)(buffer + 12));
        for (size_t i = 0; i < 6; i++)
            dst[i] = buffer[i];
        for (size_t i = 6; i < 12; i++)
            src[i - 6] = buffer[i];
        printf("目的mac:%x%x%x%x%x%x", dst[0], dst[1], dst[2], dst[3], dst[4], dst[5]);
        printf("源mac:%x%x%x%x%x%x", src[0], src[1], src[2], src[3], src[4], src[5]);
        printf("类型：%x", type);
        std::cout << std::endl;
        // arp协议数据报头
        std::cout << "arp数据包报头" << std::endl;
        // 硬件类型
        unsigned short hardware;
        // 协议类型
        unsigned short pro;
        // 硬件地址长度
        unsigned char hardware_len;
        // 协议长度
        unsigned char pro_len;
        // op
        unsigned short op;
        // 发送方mac地址
        unsigned char src_mac[7] = "\0";
        // 发送方ip地址
        std::string src_ip;
        // 目的mac地址
        unsigned char dst_mac[7] = "\0";
        // 目的ip地址
        std::string dst_ip;
        ///////////////////////////////////////////////////////////////
        hardware = ntohs(*(unsigned short *)(buffer + 14));

        pro = ntohs(*(unsigned short *)(buffer + 16));

        hardware_len = buffer[18];

        pro_len = buffer[19];

        op = ntohs(*(unsigned short *)(buffer + 20));

        for (size_t i = 22; i < 28; i++)
            src_mac[i - 22] = buffer[i];

        src_ip = inet_ntoa(*(in_addr *)(buffer + 28));

        for (size_t i = 32; i < 38; i++)
            dst_mac[i - 32] = buffer[i];

        dst_ip = inet_ntoa(*(in_addr *)(buffer + 38));
        /////////////////////////////////////////////////////////////
        printf("硬件类型：%x ", hardware);
        printf("协议类型：%x ", pro);
        printf("硬件长度：%x ", hardware_len);
        printf("协议长度：%x ", pro_len);
        printf("op:%x ", op);
        printf("源mac:%x%x%x%x%x%x ", src_mac[0], src_mac[1], src_mac[2], src_mac[3], src_mac[4], src_mac[5]);
        std::cout << "源ip" << src_ip << " ";
        printf("目的mac:%x%x%x%x%x%x ", dst_mac[0], dst_mac[1], dst_mac[2], dst_mac[3], dst_mac[4], dst_mac[5]);
        std::cout << "目的ip" << dst_ip << " ";
        std::cout << std::endl;
    }
    // 完成之后关闭文件
    close(sockfd);
    return 0;
}